
use clap::Args;
use serde::{Deserialize, Serialize};
use wtask_base::{error::{WError, WResult}, export::log_debug, tcp::{WTcpStream, stream_read_data, stream_write_data}};

use crate::{task::{cmd::AppCmd, utils::meta::{CmdArgs, CmdRet, TaskSubmitMeta}}, utils::{AppTrait, StreamStatus}};







#[derive(Debug, Clone, Serialize, Deserialize, Args)]
pub struct AppTaskSubmit {
    #[command(flatten)]
    data: TaskSubmitMeta,

    /// 不等待程序结束，立即返回程序运行状态
    #[arg(long)]
    pub no_wait: bool,
}

impl From<TaskSubmitMeta> for AppTaskSubmit {
    fn from(value: TaskSubmitMeta) -> Self {
        Self { data: value, no_wait: false }
    }
}


impl AppTrait for AppTaskSubmit {
    type Status = ();
    type Res = CmdRet;
    
    async fn client_handle<M: FnMut(bool, String) + Send + Sync>(self, stream: &WTcpStream, key: &str, mut msg_func: M, _status: Option<Self::Status>) -> WResult<Self::Res> {
        let msg = stream_read_data::<String>(
            stream.0.as_ref(),
            key,
        ).await?;
        if msg != "normal" {
            msg_func(true, msg);
            return Err(WError::Stop);
        }
        Self::client_wait_log(stream, key, msg_func).await
    }

    async fn server_handle(self, _server_token: &str, session_token: &str, stream_session: &WTcpStream, _stream_status: StreamStatus) -> WResult<()> {
        log_debug!("server {:?}", self);
        let exe_temp = format!("{}@{}", self.data.app, self.data.version);
        let cmd_args: Result<CmdArgs, WError> = self.data.try_into();
        if let Err(e) = cmd_args {
            stream_write_data(&e.to_string(), stream_session.1.as_ref(), session_token).await?;
            return Ok(());
        } else {
            stream_write_data(&"normal".to_owned(), stream_session.1.as_ref(), session_token).await?;
        }
        let cmd_server = AppCmd {
            data: cmd_args.unwrap(),
            no_wait: self.no_wait,
        };
        cmd_server.server(exe_temp, session_token, stream_session).await
    }
}

